﻿using System;
using System.Collections.Generic;
using Sinacor.Infra.Common.Exceptions;
using Sinacor.Infra.Service.ExceptionHandling;
using System.Text;
using Sinacor.Servico.Bovespa.Ordens.BusinessEntity;
using Sinacor.Servico.Bovespa.Ordens.ResourceAccess;
using Sinacor.Servico.Bovespa.Comum.ResourceAccess;
using Sinacor.Servico.Bovespa.Calendario.ResourceAccess;
using Sinacor.Infra.Service.Common;
using Sinacor.Infra.Service.Validation;


namespace Sinacor.Servico.Bovespa.Cliente.BusinessLogic
{
    public class Correspondente : BaseBusinessLogic
    {
        #region Constantes

        private const int ERRO_CLIENTEINVALIDO = 109351;
        private const int ERRO_CLIENTEINEXISTENTE = 109399;
        private const int ERRO_CORRESPONDENTEDUPLICADO = 109400;
        private const int ERRO_IND_BROKER = 109737;

        #endregion

        #region Contrutor

        /// <summary>
        /// Construtor padrão
        /// </summary>
        public Correspondente()
            : base()
        { }

        #endregion

        #region Metodos

        /// Data:04/02/2008 15:58
        /// Autor:DMilanez.7Comm
        /// Obs:
        /// Correcao
        /// Parametros de Entrada foram alterados
        public bool VerificarExigenciaDigitacao(string codigoBolsa, int codigoEmpresa)
        {
            ResourceAccess.Correspondente correspondente = new ResourceAccess.Correspondente();
            return correspondente.VerificarExigenciaDigitacao(codigoBolsa, codigoEmpresa);
        }

        /// <summary>
        /// Data:11/02/2008 16:01
        /// Autor:DMilanez.7Comm
        /// Obs:
        /// </summary>
        /// <param name="codigoBolsa"></param>
        /// <param name="codigoEmpresa"></param>
        /// <returns></returns>
        public bool VerificarSePodeExistirDigitacaoCorrespondente()
        {
            ResourceAccess.Correspondente correspondente = new ResourceAccess.Correspondente();
            return correspondente.VerificarSePodeExistirDigitacaoCorrespondente();
        }

        /// Data:04/02/2008 15:58
        /// Autor:DMilanez.7Comm
        /// Obs:
        /// Parametro de entrada foi renomeado
        public Decimal? RecuperarPercentualComissao(int codigoCorrespondente)
        {
            ResourceAccess.Correspondente correspondente = new ResourceAccess.Correspondente();
            return correspondente.RecuperarPercentualComissao(codigoCorrespondente);
        }

        /// <summary>
        /// Data:26/02/2008 14:16
        /// Autor:dmilanez.7comm
        /// Obs: 
        /// </summary>
        /// <param name="codigoCorrespondente"></param>
        /// <returns></returns>
        public bool VerificarExistencia(int codigoCorrespondente)
        {
            ResourceAccess.Correspondente correspondente = new ResourceAccess.Correspondente();
            return correspondente.VerificarExistencia(codigoCorrespondente);
        }

        /// Data:20/04/2008 17:54
        /// Autor:DMilanez.7Comm
        /// Obs: Metodo responsavel por consultar um correspondente
        public Sinacor.Servico.Bovespa.Cliente.BusinessEntity.Correspondente Consultar(Sinacor.Servico.Bovespa.Cliente.BusinessEntity.Correspondente request)
        {
            if (request == null)
                return null;

            //TODO: Disparar ValidationException informando que o codigo deve ser informado
            if (!request.Codigo.HasValue)
                return null;

            ResourceAccess.Correspondente correspondente = new ResourceAccess.Correspondente();
            return correspondente.Consultar(request);
        }

        //Task : 5435
        //Data : 27/02/2009
        //Autor: Andre
        /// <summary>
        /// Retornar a lista  de correspondente da resource para a service
        /// </summary>
        /// <returns></returns>

        /// Historico:
        /// Data : 10/08/2009
        /// Autor: Felipe Barbosa Gonzalez
        /// 7Comm Informativa   
        /// Obs.: Criado os metodos ValidarCorrespondente, VerificarCorrespondenteExistente, VerificarCodigoCliente,AlterarCorrespondente
        /// AlterarCorrespondentes, ConsultarCorrespondentes, ConsultarCorrespondente, ExcluirCorrespondente, ExcluirCorrespondentes
        /// IncluirCorrespondente,IncluirCorrespondente
        private void ValidarCorrespondente(Sinacor.Servico.Bovespa.Cliente.BusinessEntity.Correspondente request)
        {
            Parametro.BusinessLogic.ParametroBolsa blParametroBolsa = new Parametro.BusinessLogic.ParametroBolsa();
            Parametro.BusinessEntity.ParametroBolsa paramBolsa = null;
            
            //Validação de RuleSe objeto: BusinessEntity.Correspondente
            SinacorValidation validacao = new SinacorValidation();
            validacao.Validate<BusinessEntity.Correspondente>(request);

            //Obtem parametro bolsa
            paramBolsa = blParametroBolsa.ObterParametroBolsa();

            //Verifica se o registro pode ser broker
            if (paramBolsa != null && !paramBolsa.Correspondente && !request.IndicadorBroker)
                throw new BusinessException(ERRO_IND_BROKER);

            //Atribuindo código do request para filtro
            BusinessEntity.Parameter.FiltroCliente filtro = new Sinacor.Servico.Bovespa.Cliente.BusinessEntity.Parameter.FiltroCliente();
            if (request.Codigo.HasValue)
            {
                filtro.Codigo = request.Codigo.Value;
            }
            //Verificação se cliente é válido
            if (!this.VerificarCodigoCliente(filtro))
            {
                BusinessException ex = new BusinessException(ERRO_CLIENTEINEXISTENTE);
                throw ex;
            }
        }

        private bool VerificarCorrespondenteExistente(Sinacor.Servico.Bovespa.Cliente.BusinessEntity.Parameter.FiltroCorrespondenteChave filtro)
        {
            if (new ResourceAccess.Correspondente().ObterCorrespondente(filtro) != null)
            {
                return true;
            }
            return false;
        }
        private bool VerificarCodigoCliente(Sinacor.Servico.Bovespa.Cliente.BusinessEntity.Parameter.FiltroClienteChave filtro)
        {
            Bovespa.Cliente.BusinessEntity.Parameter.FiltroCliente filtroChave = new Bovespa.Cliente.BusinessEntity.Parameter.FiltroCliente();

            filtroChave.Codigo = filtro.Codigo;
            if (new BusinessLogic.Cliente().ObterCliente(filtroChave) == null)
            {
                return false;
            }
            return true;
        }

        public void AlterarCorrespondente(Sinacor.Servico.Bovespa.Cliente.BusinessEntity.Correspondente request)
        {
            //Valida se Request é nulo
            if (request == null)
            {
                ValidationException ex = new ValidationException(ERRO_CLIENTEINVALIDO);
                throw ex;
            }
            //Realiza validação de Correspondente
            this.ValidarCorrespondente(request);
            
            //Alteração
            new ResourceAccess.Correspondente().AlterarCorrespondente(request);
        }

        public void AlterarCorrespondentes(List<Sinacor.Servico.Bovespa.Cliente.BusinessEntity.Correspondente> request)
        {
            foreach (BusinessEntity.Correspondente item in request)
            {
                AlterarCorrespondente(item);
            }
        }

        public List<Sinacor.Servico.Bovespa.Cliente.BusinessEntity.Correspondente> ConsultarCorrespondentes(Sinacor.Servico.Bovespa.Cliente.BusinessEntity.Parameter.FiltroCorrespondente filtroCorrespondente)
        {
            if (filtroCorrespondente == null)
            {
                ValidationException ex = new ValidationException(ERRO_CLIENTEINVALIDO);
                throw ex;
            }
            return new ResourceAccess.Correspondente().ConsultarCorrespondentes(filtroCorrespondente);

        }
        // Data: 05/11/2009
        // Autor: Apsilva
        // Refactoring 11213
        /// <summary>
        /// Exclui uma lista de correspondentes a partir de seu código.
        /// </summary>
        /// <param name="filtroCorrespondente"></param>
        /// <param name="parametro"></param>
        private  void ExcluirCorrespondente(Sinacor.Servico.Bovespa.Cliente.BusinessEntity.Parameter.FiltroCorrespondenteChave filtroCorrespondente, Parametro.BusinessEntity.Parametro parametro)
        {
            if (filtroCorrespondente != null && parametro != null)
            {

                if (parametro.CodigoAgenteCompensacao == null || parametro.CodigoAgenteCompensacao != filtroCorrespondente.Codigo)
                {
                    new ResourceAccess.Correspondente().ExcluirCorrespondente(filtroCorrespondente);
                    
                }
                else
                {
                    throw new BusinessException(109576);

                }
            }

            else
            {
                throw new BusinessException(109351); 
            }
        }

        // Data: 05/11/2009
        // Autor: Apsilva
        // Refactoring 11213
        /// <summary>
        /// Exclui um correspondente.
        /// </summary>
        /// <param name="filtroCorrespondente"></param>
        public void ExcluirCorrespondente(BusinessEntity.Parameter.FiltroCorrespondenteChave filtroCorrespondente) 
        {
            Parametro.BusinessEntity.Parametro parametro = new  Parametro.BusinessLogic.Parametro().ObterParametro();
            ExcluirCorrespondente(filtroCorrespondente, parametro ); 
        }

        // Data: 05/11/2009
        // Autor: Apsilva
        // Refactoring 11213
        /// <summary>
        /// Exclui um correspondente a partir de seu código.
        /// </summary>
        /// <param name="filtroCorrespondentes"></param>
        public void ExcluirCorrespondentes(List<Sinacor.Servico.Bovespa.Cliente.BusinessEntity.Parameter.FiltroCorrespondenteChave> filtroCorrespondentes)
        {
            Parametro.BusinessEntity.Parametro parametro = new Parametro.BusinessLogic.Parametro().ObterParametro();
            foreach (BusinessEntity.Parameter.FiltroCorrespondenteChave item in filtroCorrespondentes)
            {
                this.ExcluirCorrespondente(item, parametro);
            }
        }

        public void IncluirCorrespondente(BusinessEntity.Correspondente correspondente)
        {
            //Valida se Request é nulo
            if (correspondente == null)
            {
                ValidationException ex = new ValidationException(ERRO_CLIENTEINVALIDO);
                throw ex;
            }

            //Realiza validação de Correspondente
            this.ValidarCorrespondente(correspondente);

            //criando filtro
            Sinacor.Servico.Bovespa.Cliente.BusinessEntity.Parameter.FiltroCorrespondenteChave filtroCorrespondenteChave = new Sinacor.Servico.Bovespa.Cliente.BusinessEntity.Parameter.FiltroCorrespondenteChave();
            filtroCorrespondenteChave.Codigo = correspondente.Codigo.Value;
            BusinessEntity.Parameter.FiltroCliente filtro = new Sinacor.Servico.Bovespa.Cliente.BusinessEntity.Parameter.FiltroCliente();

            if (correspondente.Codigo.HasValue)
            {
                filtro.Codigo = correspondente.Codigo.Value;
            }

            //Verificar duplicidade de correspondente
            if (this.VerificarCorrespondenteExistente(filtroCorrespondenteChave))
            {
                BusinessException ex = new BusinessException(ERRO_CORRESPONDENTEDUPLICADO);
                throw ex;
            }
            
            //Inclusão
            new ResourceAccess.Correspondente().IncluirCorrespondente(correspondente);
        }
        public void IncluirCorrespondentes(List<BusinessEntity.Correspondente> correspondentes)
        {
            foreach (BusinessEntity.Correspondente item in correspondentes)
            {
                IncluirCorrespondente(item);
            }
        }
        public void ExecutarTransacoes(List<BusinessEntity.Correspondente> inclusoes, List<BusinessEntity.Parameter.FiltroCorrespondenteChave> exclusoes, List<BusinessEntity.Correspondente> alteracoes)
        {
            this.IncluirCorrespondentes(inclusoes);
            this.ExcluirCorrespondentes(exclusoes);
            this.AlterarCorrespondentes(alteracoes);
        }

        #endregion
    }
}
